package com.macoli.mock_server

import android.app.*
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Build
import android.os.IBinder
import android.os.Process
import androidx.core.app.NotificationCompat
import com.macoli.mock_server.common.Configuration
import com.macoli.mock_server.di.component.BaseComponent
import com.macoli.mock_server.di.component.DaggerBaseComponent
import com.macoli.mock_server.httpserver.HttpServer
import com.macoli.mock_server.httpserver.beans.Destnation
import com.macoli.mock_server.httpserver.module.RouterModule
import com.macoli.mock_server.httpserver.route.Router
import kotlinx.coroutines.*
import java.lang.Runnable
import javax.inject.Inject


class MockService : Service() {

    companion object {
        @JvmStatic
        fun startMockService(context : Context, mainActivityClass : Class<*>
                             , configPath : String , destnationList : ArrayList<Destnation>?) {
            val intent = Intent(context , MockService::class.java)
            intent.putExtra("main_class" , mainActivityClass)
            intent.putExtra("configPath" , configPath)
            intent.putExtra("destnationList" , destnationList)

            context.startService(intent)
        }
        private lateinit var instance: MockService



        fun getMockService() : MockService {
            return instance
        }


    }

    var mServiceConnection : AssistServiceConnection? = null;

    private val NOTIFICATION_ID = Process.myPid()

    private var mMainActivityClass : Class<*>? = null;

    @Inject
    lateinit var router: Router
    @Inject
    lateinit var configuration: Configuration

    private var serverComplete = false

    private var parseConfigurationJob : Job? = null

    private lateinit var daggerBaseComponent: BaseComponent

    fun getBaseComponent() : BaseComponent {
        return daggerBaseComponent
    }

    override fun onCreate() {
        instance = this
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
            var nm = this.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
            //数字是随便写的“40”，
            nm.createNotificationChannel(NotificationChannel("40", "App Service", NotificationManager.IMPORTANCE_DEFAULT));
            var builder = NotificationCompat.Builder(this, "40");

            //其中的2，是也随便写的，正式项目也是随便写
            startForeground(2 ,builder.build());
        }
        daggerBaseComponent = DaggerBaseComponent.builder().routerModule(RouterModule()).build()
        daggerBaseComponent.injectMockService(instance)


    }



    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        if (intent?.hasExtra("configPath") == true) {
            mMainActivityClass = intent?.extras?.get("main_class") as Class<*>?
            val configPath = intent?.extras?.get("configPath") as String
            val destnationList = intent?.extras?.get("destnationList") as ArrayList<Destnation>

            if (!serverComplete) {
                parseConfigurationJob = GlobalScope.launch(Dispatchers.IO){
                    configuration.parseConfiguration(configPath)
                    for (destnation in destnationList) {
                        router.addDestnation(destnation)
                    }

                    HttpServer(configuration.hostName , configuration.port).start()
                }
            }
            Thread(mRunnable).start()
            // 设置为前台进程，降低oom_adj，提高进程优先级，提高存活机率
            setForeground();
        }

        return START_STICKY;

    }

    // 要注意的是android4.3之后Service.startForeground() 会强制弹出通知栏，解决办法是再
    // 启动一个service和推送共用一个通知栏，然后stop这个service使得通知栏消失。
    fun setForeground() {
        if (Build.VERSION.SDK_INT < 18)
        {
            startForeground(NOTIFICATION_ID, getNotification());
            return;
        }
        if (mServiceConnection == null)
        {
            mServiceConnection = AssistServiceConnection();
        }
        // 绑定另外一条Service，目的是再启动一个通知，然后马上关闭。以达到通知栏没有相关通知
        // 的效果
        var intent : Intent = Intent(this, AssistService::class.java)
        bindService(intent , mServiceConnection!!,
            Service.BIND_AUTO_CREATE);
    }

    override fun onDestroy() {
        super.onDestroy()
        parseConfigurationJob?.cancel()
    }

    override fun onBind(p0: Intent?): IBinder? {
        return null ;
    }




    inner class AssistServiceConnection : ServiceConnection {
        override fun onServiceConnected(p0: ComponentName?, service: IBinder?) {
            val assistService: Service = (service as AssistService.LocalBinder)
                .getService()
            this@MockService.startForeground(NOTIFICATION_ID, getNotification())
            assistService.startForeground(NOTIFICATION_ID, getNotification())
            assistService.stopForeground(true)

            this@MockService.unbindService(mServiceConnection!!)
//            mServiceConnection = null
        }

        override fun onServiceDisconnected(p0: ComponentName?) {

        }

    }

    fun getNotification(): Notification {
        val CHANNEL_ONE_ID = "CHANNEL_ONE_ID"
        val CHANNEL_ONE_NAME = "CHANNEL_ONE_ID"
        val notificationChannel: NotificationChannel
//进行8.0的判断
//进行8.0的判断
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            notificationChannel = NotificationChannel(
                CHANNEL_ONE_ID,
                CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_HIGH
            )
            notificationChannel.enableLights(true)
            notificationChannel.setShowBadge(true)
            notificationChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
            val manager =
                getSystemService(NOTIFICATION_SERVICE) as NotificationManager
            manager?.createNotificationChannel(notificationChannel)
        }
        val intent = Intent(this, mMainActivityClass)
        val pendingFlags: Int
        pendingFlags = PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        val pendingIntent = PendingIntent.getActivity(this, 0, intent, pendingFlags)

        return Notification.Builder(this, CHANNEL_ONE_ID).setChannelId(CHANNEL_ONE_ID)
            .setTicker("Nature")
            .setSmallIcon(R.drawable.faker)
            .setContentTitle("Dynamic mock server")
            .setContentIntent(pendingIntent)
//            .setContentText("http://${HTTP_IP}:${HTTP_PORT} , ${mPresenter.getWebSocketAddr() ?: ""}")
            .build();
    }

    var mRunnable = Runnable() {
            while (true)
            {
                var intent = Intent();
                //指定广播的名字
                intent.setAction("com.yy.time.TIME_CHANGED_ACTION");
                //指定广播的内容
                // 此行  对8.0以上广播接受不到 增加处理 “包名” ，“广播地址” intent.setComponent( new ComponentName( "com.example.webwebsocket" ,
                //"com.example.webwebsocket.Service.UITimeReceiver"));

                try {
                    intent.setComponent( ComponentName( "com.example.webwebsocket" ,
                        "com.example.webwebsocket.Service.UITimeReceiver") );

                    //此处我传递了值   你们不传递也行
                    intent.putExtra("time",12);
                } catch (e : Exception) {
                    e.printStackTrace();
                }
                //发送广播
                sendBroadcast(intent);
                try {
                    Thread.sleep(1000);
                } catch ( e : InterruptedException) {
                    e.printStackTrace();
                }
            }

    }
}